package br.edu.ufcg.compiladores.brasigol.geracao;
import br.edu.ufcg.compiladores.brasigol.semantico.TipoDeDado;

/**
 * @author Marcelo Emanoel
 * 
 */
public enum ComandosPSN {

	INPUT {
		public String toString() {
			return (isTipoInteiro() ? "inp-i" : "inp-s");
		}
	},
	OUTPUT_VARIAVEL {
		public String toString() {
			return (isTipoInteiro() ? "out-i" : "out-s");
		}
	},
	OUTPUT_CONSTANTE {
		public String toString() {
			return (isTipoInteiro() ? "out-ci" : "out-cs");
		}
	},
	OUTPUT_NOVA_LINHA {
		public String toString() {
			return "out-nl";
		}
	},
	SOMA {
		public String toString() {
			return "+";
		}
	},
	DIVISAO {
		public String toString() {
			return "/";
		}
	},
	MULTIPLICACAO {
		public String toString() {
			return "*";
		}
	},
	SUBTRACAO {
		public String toString() {
			return "-";
		}
	},
	EXPONENCIACAO {
		public String toString() {
			return "**";
		}
	},
	MAIOR {
		public String toString() {
			return ">";
		}
	},
	MAIOR_IGUAL {
		public String toString() {
			return ">=";
		}
	},
	MENOR {
		public String toString() {
			return "<";
		}
	},
	MENOR_IGUAL {
		public String toString() {
			return "<=";
		}
	},
	IGUAL {
		public String toString() {
			return "==";
		}
	},
	DIFERENTE {
		public String toString() {
			return "!=";
		}
	},
	IF {
		public String toString() {
			return "jif";
		}
	},
	JUMP {
		public String toString() {
			return "jmp";
		}
	},
	CALL {
		public String toString() {
			return "jsb";
		}
	},
	RET {
		public String toString() {
			return "ret";
		}
	},
	END {
		public String toString() {
			return "hlt";
		}
	},
	ATRIBUICAO {
		public String toString() {
			return ":=";
		}
	};

	TipoDeDado tipo;
	
	public static ComandosPSN build(String valor){
		for(ComandosPSN cmd : values()){
			if(cmd != INPUT && cmd != OUTPUT_CONSTANTE && cmd != OUTPUT_VARIAVEL && cmd.toString().equalsIgnoreCase(valor)){
				return cmd;
			}
		}
		return null;
	}
	
	public void setTipo(TipoDeDado tipo) {
		this.tipo = tipo;
	}

	boolean isTipoInteiro() {
		return getTipo().equals(TipoDeDado.INTEIRO);
	}

	public TipoDeDado getTipo() {
		return tipo;
	}
}
